package zdc {
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.IBitmapDrawable;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageDisplayState;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.Capabilities;
import flash.utils.Timer;
import flash.utils.getDefinitionByName;

/**
 * ...
 * @author Simple Slime
 */
public class Util {

    /**
     * 随机正负数
     * @return
     */
    public static function get rsign():int {
        if (Math.random() < 0.5) {
            return 1;
        }
        else {
            return -1;
        }
    }

    /**
     *
     * @param    max
     * @param    min
     * @return
     */
    public static function rndRange(max:Number, min:Number):Number {
        return Math.random() * (max - min) + min;
    }

    /**
     * 获取颜色alpha值
     * @param    color
     * @return
     */
    public static function getAlpha(color:uint):uint {
        return ((color >> 24) & 0xff);
    }

    /**
     * 获取颜色red值
     * @param    color
     * @return
     */
    public static function getRed(color:uint):uint {
        return ((color >> 16) & 0xff);
    }

    /**
     * 获取颜色green值
     * @param    color
     * @return
     */
    public static function getGreen(color:uint):uint {
        return ((color >> 8) & 0xff);
    }

    /**
     * 获取颜色blue值
     * @param    color
     * @return
     */
    public static function getBlue(color:uint):uint {
        return (color & 0xff);
    }

    /**
     * 验证字符串，集合类是否为空
     * @param    str
     */
    public static function isEmpty(obj:Object):Boolean {
        if (obj is String) {
            if (/^\s*$/g.test(obj as String)) {
                return true;
            }
            return false;
        }

        if (obj is Array || obj is Vector) {
            if (!obj || obj.length == 0) {
                return false;
            }
            return true;
        }

        return false;
    }

    /**
     * 验证字符串是否为整数
     * @param    str
     * @param    ignoreWhiteSpace
     * @param     len                    确定指定位数的整数
     * @return
     */
    public static function isInt(str:String, ignoreWhiteSpace:Boolean = false, len:int = 0):Boolean {
        if (ignoreWhiteSpace) {
            str = trim(str);
        }
        var reg:RegExp = new RegExp("^\\d" + (len == 0 ? "+" : ("{" + len + "}")) + "$", "g");
        if (reg.test(str)) {
            return true;
        }
        return false;
    }

    /**
     * 剔除首尾的空白
     * @param    str
     * @return
     */
    public static function trim(str:String):String {
        var reg:RegExp = /(^\s*)|(\s*$)/g;
        return str.replace(reg, "");
    }

    /**
     * 获取类
     * @param    loader
     * @param    clsName
     * @return
     */
    public static function getClass(loaderInfo:LoaderInfo, clsName:String):Class {
        try {
            return loaderInfo.applicationDomain.getDefinition(clsName) as Class;
        }
        catch (e:Error) {
            return null;
        }
        return null;
    }

    /**
     * 填充字符串
     * @param    str
     * @param    space
     * @param    padstr
     * @param    left
     * @return
     */
    public static function paddingString(str:String, space:int, padstr:String, left:Boolean = true):String {
        var num:int = space - str.length;
        if (num > 0) {
            str = (left ? dupString(padstr.substr(0, 1), num) : "") + str + (!left ? dupString(padstr[0], num) : "");
        }
        return str;
    }

    /**
     * 复制字符串
     * @param    str
     * @param    count
     * @return
     */
    public static function dupString(str:String, count:uint):String {
        var temp:Array = [];
        for (var i:int = 0; i < count; i++) {
            temp.push(str);
        }
        return temp.join("");
    }

    /**
     * 清除所有子对象
     * @param    container
     * @param    exclude            排除的对象
     */
    public static function clearChildren(container:DisplayObjectContainer, exclude:Array = null):void {
        for (var i:int = container.numChildren - 1; i >= 0; i--) {
            var child:DisplayObject = container.getChildAt(i);
            if (exclude && exclude.indexOf(child) > -1) {
                continue;
            }
            else {
                container.removeChildAt(i);
            }
        }
    }

    /**
     * 在一定范围内保持比例获取最合适的宽和高
     * @param    w
     * @param    h
     * @param    maxW
     * @param    maxH
     * @return
     */
    public static function getRatioSize(w:Number, h:Number, maxW:int, maxH:int):Point {
        var ratio:Number = maxW / maxH;
        var scale:Number;
        if (w > maxW || w < maxW) {
            scale = maxW / w;
            w = maxW;
            h *= scale;
        }
        if (h > maxH || h < maxH) {
            scale = maxH / h;
            h = maxH;
            if (w * scale < w) {
                w *= scale;
            }
        }
        return new Point(w, h);
    }

    /**
     * 混合两个对象并返回新对象
     * @param    obj1
     * @param    obj2
     * @param    overwrite
     */
    public static function mix(obj1:Object, obj2:Object, overwrite:Boolean = true):Object {
        var tempObj:Object = { };
        if (obj1) {
            for (var p1:String in obj1) {
                tempObj[p1] = obj1[p1];
            }
        }
        if (obj2) {
            for (var p2:String in obj2) {
                if (!tempObj.hasOwnProperty(p2) || overwrite) {
                    tempObj[p2] = obj2[p2];
                }
            }
        }
        return tempObj;
    }

    /**
     * 把显示对象置顶
     * @param    dio
     */
    public static function top(dio:DisplayObject):void {
        var p:DisplayObjectContainer = dio.parent;
        if (p) {
            p.setChildIndex(dio, p.numChildren - 1);
        }
    }

    /**
     * 置顶所有对象，从左往右依次递减
     * @param    arr
     */
    public static function topAll(arr:Array):void {
        for (var i:int = arr.length - 1; i >= 0; i--) {
            top(arr[i]);
        }
    }

    /**
     * 获取显示对象的深度
     * @param    dio
     * @return
     */
    public static function deep(dio:DisplayObject):int {
        if (!dio) {
            return -1;
        }
        var p:DisplayObjectContainer = dio.parent;
        if (p) {
            return p.getChildIndex(dio);
        }
        return -1;
    }

    /**
     * 获取显示对象列表的深度
     * @param    dio
     * @return
     */
    public static function deeps(dios:Array):Array {
        var temp:Array = [];
        for (var i:int = 0; i < dios.length; i++) {
            temp.push(deep(dios[i]));
        }
        return temp;
    }

    /**
     * 设置深度为最下
     * @param    dio
     * @return
     */
    public static function bottom(dio:DisplayObject):void {
        var p:DisplayObjectContainer = dio.parent;
        if (p) {
            p.setChildIndex(dio, 0);
        }
    }

    /**
     * 设置深度为最下
     * @param    dio
     * @return
     */
    public static function bottoms(dios:Array):void {
        for (var i:int = dios.length - 1; i >= 0; i--) {
            bottom(dios[i]);
        }
    }

    /**
     * 抽取数字
     * @param    str
     * @return
     */
    public static function extractNum(str:String):String {
        return str.replace(/\D/gi, "");
    }

    /**
     * 延迟执行
     * @param    func    执行函数
     * @param    time    秒
     */
    public static function delay(func:Function, time:Number):void {
        var timer:Timer = new Timer(time * 1000, 1);
        var handler:Function = function (e:TimerEvent):void {
            timer.removeEventListener(TimerEvent.TIMER_COMPLETE, handler);
            func();
        };
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, handler);
        timer.start();
    }

    /**
     * 依次播放队列
     * @param    mcs
     * @param    endFun
     */
    public static function playQueue(mcs:Array, endFun:Function = null):Array {
        var sp:Sprite = mcs[0];
        var i:int = 0;

        var handler:Function = function (e:Event):void {
            var mc:MovieClip = mcs[i];		//trace(i, mc.currentFrame, mc.totalFrames);
            mc.play();
            if (mc.currentFrame == mc.totalFrames && i < mcs.length - 1) {
                i++;
                var next:MovieClip = mcs[i];
                //next.gotoAndPlay(Math.min(next.currentFrame + 1, next.totalFrames));
                next.gotoAndPlay(1);
            }
            else if (i >= mcs.length - 1 && mc.currentFrame == mc.totalFrames) {
                sp.removeEventListener(Event.ENTER_FRAME, handler);
                endFun && endFun();
                //trace("play over", i);
            }
        }
        sp.addEventListener(Event.ENTER_FRAME, handler);
        return [sp, handler];
    }

    /**
     * 放置在舞台中心
     * @param    dio
     * @param    dir
     */
    public static function centerStage(dio:DisplayObject, dir:String = 'hv', stageWidth:Number = 0, stageHeight:Number = 0):void {
        var stage:Stage = dio.stage;
        var stw:Number, sth:Number;

        stw = stageWidth ? stageWidth : stage.stageWidth;
        sth = stageHeight ? stageHeight : stage.stageHeight;

        if (dir.indexOf('h')) {
            dio.x = stw - dio.width >> 1;
        }
        if (dir.indexOf('v')) {
            dio.y = sth - dio.height >> 1;
        }
    }

    /**
     * 删除显示对象
     * @param    dio
     */
    public static function rmChild(dio:DisplayObject):void {
        if (dio.parent) {
            dio.parent.removeChild(dio);
        }
    }

    /**
     * 添加多个子对象
     * @param    par
     * @param    children
     */
    public static function addChildren(par:DisplayObjectContainer, children:Array):void {
        for (var i:int = 0; i < children.length; i++) {
            par.addChild(children[i]);
        }
    }

    /**
     * 首字母大写
     * @param    str
     * @return
     */
    public static function capitalize(str:String):String {
        return str.substr(0, 1).toUpperCase() + str.substr(1);
    }

    /**
     * 首字母小写
     * @param    str
     * @return
     */
    public static function uncapitalize(str:String):String {
        return str.substr(0, 1).toLocaleLowerCase() + str.substr(1);
    }

    /**
     * 把对象中心移到父对象的原点
     * @param    dio
     */
    public static function regCent(dio:DisplayObject):void {
        if (dio.parent) {
            dio.x = -dio.width / 2;
            dio.y = -dio.height / 2;
        }
    }

    /**
     * 获取最大和最小的索引
     * @param    coll            数组
     * @param    by                排序属性
     * @return                    最大和最小的索引
     */
    public static function mostIndex(coll:Array, by:Object):Array {
        var tempArr:Array = coll.sortOn(by, Array.NUMERIC | Array.DESCENDING | Array.RETURNINDEXEDARRAY);
        trace(tempArr);

        if (tempArr.length < 1) {
            return [ -1, -1 ];
        }
        else if (tempArr.length == 1) {
            return [0, 0];
        }
        else {
            return [tempArr[0], tempArr[tempArr.length - 1]];
        }
    }

    /**
     * 获取最大和最小的索引
     * @param    arr
     * @param    sortFun
     * @return
     */
    public static function sortedIndex(arr:Array, sortFun:Function):Array {
        var tempArr:Array = arr.concat([]);
        tempArr.sort(sortFun);

        if (tempArr.length < 1) {
            return [-1, -1];
        }
        else if (tempArr.length == 1) {
            return [0, 0];
        }
        else {
            return [arr.indexOf(tempArr[0]), arr.indexOf(tempArr[tempArr.length - 1])];
        }
    }

    /**
     * vector转数组
     * @param    vec
     * @return
     */
    public static function toArr(vec:Vector):Array {
        var arr:Array = [];
        for (var i:int = 0; i < vec.length; i++) {
            arr.push(vec[i]);
        }
        return arr;
    }

    /**
     * 全屏
     * @param    stage
     * @param    align
     * @param    scale
     * @param    state
     */
    public static function fullScreen(stage:Stage, scale:String = StageScaleMode.NO_SCALE, align:String = StageAlign.TOP_LEFT, state:String = StageDisplayState.FULL_SCREEN):void {
        stage.align = align;
        stage.scaleMode = scale;
        stage.displayState = state;
    }

    /**
     * 运行环境是否在Windows系统
     * @return
     */
    public static function get isWindows():Boolean {
        return Capabilities.version.indexOf("WIN") > -1;
    }

    /**
     * 运行环境是否在Macintosh系统
     * @return
     */
    public static function get isMacintosh():Boolean {
        return Capabilities.version.indexOf("MAC") > -1;
    }

    /**
     * 运行环境是否在Linux系统
     * @return
     */
    public static function get isLinux():Boolean {
        return Capabilities.version.indexOf("LNX") > -1;
    }

    /**
     * 运行环境是否在Android系统
     * @return
     */
    public static function get isAndroid():Boolean {
        return Capabilities.version.indexOf("AND") > -1;
    }

    /**
     * 返回数字所属数组中的位置，如6在 [1, 5, 10]中的索引为1
     * @param    arr
     * @param    num
     * @return
     */
    public static function inNumPart(arr:Array, num:int):int {
        for (var i:int = 0; i < arr.length; i++) {			//trace(num, "arr[i]:", arr[i]);
            if (num >= arr[i]) {
                if (i == arr.length - 1) {
                    return i;
                }
                else {
                    continue;
                }
            }
            else {
                return i - 1;
            }
        }
        trace("out");
        return 0;
    }

    /**
     * 把数组元素相加
     * @param    arr
     * @param    fun
     * @return
     */
    public static function sumArr(arr:Array, fun:Function):Number {
        var sum:Number = 0;
        for (var i:int = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    /**
     * 显示前后按钮
     * @param    prev
     * @param    next
     * @param    total
     * @param    idx            从0开始
     */
    public static function displayPNBtn(prev:DisplayObject, next:DisplayObject, total:int, idx:int):void {
        prev.visible = next.visible = true;				//trace("displayPNBtn:", idx < 1, idx >= total - 1, idx);
        if (idx < 1) {
            prev.visible = false;
        }
        if (idx >= total - 1) {
            next.visible = false;
        }
    }

    /**
     * 更改bpd的尺寸
     * @param bpd
     * @param wid
     * @param hei
     */
    public static function sizeBpd(bpd:BitmapData, wid:Number, hei:Number):BitmapData {
        var m:Matrix = new Matrix();
        m.scale(wid / bpd.width, hei / bpd.height);
        var d:BitmapData = new BitmapData(wid, hei, true, 0);
        d.draw(bpd, m, null, null, null, true);
        return d;
    }

    /**
     * 获取显示对象的注册点为中心点的包装Sprite
     * @param dio
     * @return
     */
    public static function centerRegSp(dio:DisplayObject):Sprite {
        var sp:Sprite = new Sprite();
        sp.addChild(dio);
        dio.x = -(dio.width >> 1);
        dio.y = -(dio.height >> 1);
        return sp;
    }

    /**
     * 获取显示对象的bitmapdata
     * @param dio
     * @param smoothing
     * @param matrix
     * @param colorTransform
     * @param blendMode
     * @param clipRect
     * @return
     */
    public static function getDioBpd(dio:DisplayObject, smoothing:Boolean = false, matrix:Matrix = null, colorTransform:ColorTransform = null, blendMode:String = null, clipRect:Rectangle = null):BitmapData {
        var bpd:BitmapData = new BitmapData(dio.width, dio.height, true, 0);
        bpd.draw(dio, matrix, colorTransform, blendMode, clipRect, smoothing);
        return bpd;
    }

    /**
     * 设置深度
     * @param dio
     * @param deep
     */
    public static function setDeep(dio:DisplayObject, deep:int):void {
        var p:DisplayObjectContainer = dio.parent;
        if (p) {
            p.setChildIndex(dio, deep);
        }
    }

    /**
     * 获取定义
     * @param defName
     * @return
     */
    public static function getDef(defName:String):Object {
        var def:Object = null;
        try {
            def = getDefinitionByName(defName);
        }
        catch (e:Error) {
        }
        finally {
            return def;
        }
    }

    /**
     * 根据属性判断两个对象是否相等
     * @param obj1
     * @param obj2
     * @param props
     * @return
     */
    public static function objEqual(obj1:Object, obj2:Object, props:Array):Boolean {
        var equ:Boolean = true;
        for each(var key:String in props){
            if(obj1[key] != obj2[key]){
                return false;
            }
        }
        return equ;
    }
}
}